ひとりNavigation API Advent Calendar 13日目
https://gyazo.com/92c681bb3fbb35eb6d3639d760aacd03
このIssueが起点っぽい?
そのためにpopstateやpushStateをモンキーパッチして、子アプリがナビゲーションイベントを受け取るタイミングを制御している 例:アプリのマウント/アンマウントが完了するまで、他のルーターにイベントを渡したくない
提案された API アイデア
e.withhold(promise) や e.blockUntil(promise) のような API で イベント伝播を Promise 解決までブロックできるようにしたい
この時点では preventDefault() でナビゲーションをキャンセルし、 single-spa の処理完了後に 同じ URL に再度 navigate し直すという方法が検討されていた 設計の具体的にはAppHistoryNavigateEvent.respondWith()というものが検討されていたがこれはPromiseのresolve値を返さないので、FetchEventのそれとは違っていた(由来自体はFetchEventのそれではあったみたい) なので名前としてふさわしくないのではないか?という話があった
Navigation API の respondWith() は、複数のイベントハンドラが同時に呼び出すことができないという制約があり、後続の respondWith() 呼び出しは InvalidStateError になってしまう この呼び出し方を変更していくことになったため、respondWith()だと意味が変わるため、名称変更が議論されていた
最終的に名称は transitionWhile() に変更された
この名称は、提供されたPromiseが保留中である間、アプリケーションが「遷移(transition)」状態に入ることを明示することを意図されている transitionWhile() はスクロール位置のキャプチャタイミングが不明確で、同期/非同期で挙動が破綻する問題がでた 例えば以下のような遅延処理があったときにURLはいつ更新されるべきか?についてが不明瞭ではあった
code:js
doSyncStuff();
event.transitionWhile((async () => {
await doAsyncStuff();
})());
その結果スクロール状態の復活に不整合が起きることがある
こうした問題を解決し、DOM 更新前にスクロール状態を確実に取得できるよう、handler関数を渡す新デザインが提案された
code:sample.js
event.transitionWhile(async (transition) => {
const response = await fetch(dataURL);
const data = await response.json();
transition.captureState();
await updateDOM(data);
});
最終的に transitionWhile() はCSSのtransition系のプロパティと混同されると懸念され intercept() に置き換える方向で合意して変更された